package com.mj.simulator;

import com.mj.mes.messages.MachineStatusChange;
import com.mj.mes.messages.Messages;
import com.mj.mes.messages.WorkFinished;
import com.mj.mes.messages.WorkStarted;
import com.mj.mes.rabbitMq.RabbitmqService;
import com.mj.mes.utils.DateUtil;
import org.apache.log4j.Logger;
import org.hibernate.SQLQuery;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.*;

/**
 * author : cRyann
 *
 * @create 2017-10-11
 **/
@Controller
@RequestMapping("simulator")
public class SimulatorController {
    private Logger logger = Logger.getLogger(this.getClass());

    @Autowired
    @PersistenceContext
    private EntityManager em;

    @Autowired
    private SimpMessagingTemplate template;
    @Autowired
    RabbitmqService rabbitmqService;

    private static boolean autoSimulatorStatus = false;
    private static boolean autoSimulatorWorkOrder = false;
    private static String simulatorExchange = "mj.mes.Simulator";

    @RequestMapping(value = "deviceNameComboBox", method = RequestMethod.POST)
    @ResponseBody
    public List<Map<String, String>> getDeviceNameComboBox() {
        List<Map<String, String>> list = new ArrayList<>();
        String sql = "SELECT device_name,device_position FROM sys_mechanics";
        Query query = em.createNativeQuery(sql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        list = query.getResultList();
        return list;
    }

    @RequestMapping(value = "getAutoStatusChange", method = RequestMethod.POST)
    @ResponseBody
    public Object getAutoStatusChange() {
        Map<String, String> map = new HashMap<>();
        String status = this.autoSimulatorStatus ? "Running" : "NotRun";
        map.put("msg", status);
        return map;
    }

    @RequestMapping(value = "getAutoWorkOrder", method = RequestMethod.POST)
    @ResponseBody
    public Object getAutoWorkOrder() {
        Map<String, String> map = new HashMap<>();
        String status = this.autoSimulatorWorkOrder ? "Running" : "NotRun";
        map.put("msg", status);
        return map;
    }

    @MessageMapping("/AutoStatusChange")
    @Async("TimersAsync")
    public void autoStatusChange(String changeFlag) throws InterruptedException {
        if ("Start".equals(changeFlag) && !this.autoSimulatorStatus) {
            this.autoSimulatorStatus = true;
            template.convertAndSend("/topicSimulator/AutoStatusChange", "Running");
            while (autoSimulatorStatus) {
                // 某个设备状态改变
                statusChange();
                Thread.sleep(5 * 1000);
            }
        } else if ("Stop".equals(changeFlag)) {
            this.autoSimulatorStatus = false;
            template.convertAndSend("/topicSimulator/AutoStatusChange", "NotRun");
        }
    }

    @MessageMapping("/AutoWorkOrder")
    @Async("TimersAsync")
    public void autoWorkOrder(String changeFlag) throws InterruptedException {
        if ("Start".equals(changeFlag) && !this.autoSimulatorWorkOrder) {
            this.autoSimulatorWorkOrder = true;
            template.convertAndSend("/topicSimulator/AutoWorkOrder", "Running");
            while (autoSimulatorWorkOrder) {
                String deploymentKey = randomProcess();
                //某个设备开工
                if (deploymentKey.equals("")) {
                    continue;
                }
                workOrderStart(deploymentKey);
                //随机工作时间
                Random random = new Random();
                int r = random.nextInt(15);
                Thread.sleep(r * 1000);
                //某个设备完工
                workOrderEnd(deploymentKey);
                Thread.sleep(5 * 1000);
            }
        } else if ("Stop".equals(changeFlag)) {
            this.autoSimulatorWorkOrder = false;
            template.convertAndSend("/topicSimulator/AutoWorkOrder", "NotRun");
        }
    }


    public void statusChange() {
        String machineName = randomDevice();
        MachineStatusChange msc = new MachineStatusChange();
        msc.setMachineName(machineName);
        msc.setChangeTime(DateUtil.getDateTimeFormat(new Date()));
        msc.setCurrentStatus(String.valueOf(new Random().nextInt(4) + 1));
        msc.setAlarmText("Simulator Auto Change");
        Messages<MachineStatusChange> mgs = new Messages<>();
        mgs.setFrom("Auto_Simulator");
        mgs.setTo(simulatorExchange);
        mgs.setCode("9000900");
        mgs.setMessageName("MachineStatusChange");
        mgs.setBody(msc);
        rabbitmqService.sendContractRabbitmqTopic(simulatorExchange,
                "simulator." + machineName,
                mgs);
    }

    public void workOrderStart(String deploymentKey) {
        //某个设备开工
//        String deploymentKey = randomProcess();
        WorkStarted ws = new WorkStarted();
        //配装message
        ws.setWorkOrderId("12");
        ws.setEquipmentName("Equipment_Name");
        ws.setWorkUser("User_Name");
        ws.setWorkTime(DateUtil.getDateTimeFormat(new Date()));
        ws.setChartNumber(deploymentKey);

        Messages<WorkStarted> mgs = new Messages<>();
        mgs.setFrom("Auto_Simulator");
        mgs.setTo(simulatorExchange);
        mgs.setCode("500001");
        mgs.setMessageName("WorkStarted");
        mgs.setBody(ws);

        rabbitmqService.sendContractRabbitmqTopic(simulatorExchange,
                "simulator." + deploymentKey,
                mgs);
    }

    public void workOrderEnd(String deploymentKey) {
        WorkFinished wf = new WorkFinished();
        //配装message
        wf.setWorkOrderId("12");
        wf.setEquipmentName("Equipment_Name");
        wf.setWorkUser("User_Name");
        wf.setWorkTime(DateUtil.getDateTimeFormat(new Date()));
        wf.setChartNumber(deploymentKey);

        Messages<WorkFinished> mgs = new Messages<>();
        mgs.setFrom("Auto_Simulator");
        mgs.setTo(simulatorExchange);
        mgs.setCode("500000");
        mgs.setMessageName("WorkFinished");
        mgs.setBody(wf);

        rabbitmqService.sendContractRabbitmqTopic(simulatorExchange,
                "simulator." + deploymentKey,
                mgs);
    }

    public String randomDevice() {
        Random random = new Random();
        String sql = "SELECT * FROM sys_mechanics";
        Query query = em.createNativeQuery(sql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List list = query.getResultList();
        int r = random.nextInt(list.size());
        Map map = (Map) list.get(r);
        return (String) map.get("device_position");
    }

    public String randomProcess() {
        Random random = new Random();
        String result = "";
        String sql = "SELECT * FROM act_ru_execution";
        Query query = em.createNativeQuery(sql);
        query.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
        List list = query.getResultList();
        if (list.size() > 0) {
            int r = random.nextInt(list.size());
            Map map = (Map) list.get(r);
            result = (String) map.get("PROC_DEF_ID_");
        }
        return result;
    }
}
